#include "FSM.h"

static struct FSMtype
{
	uint8_t status;			//状态机的状态
	uint16_t lenth;			//状态机要接收到的数据的长度
}FSM;

/*********************
*函数名称：FSM_Init
*函数功能：复位状态机
*输入参数：none
*输出参数：none
***********************/
//初始化状态机
void FSM_Init(void)
{
	FSM.status	=	FSM_INIT_STATUS;
	FSM.lenth	=	0;
}
/*******************************
*函数名称：FSM_GetStatus
*函数功能：获取FSM_Flag的值
*输入参数：none
*输出参数：none
*返回值  ：FSM_Flag
*******************************/
//获取状态机状态
uint8_t FSM_GetStatus(void)
{
	return FSM.status;
}
/*******************************
*函数名称：FSM_ChangeStatus
*函数功能：给FSM_Flag的值
*输入参数：需要给FSM_Flag的状态
*输出参数：none
*******************************/
void FSM_ChangeStatus(uint8_t status)
{
	FSM.status	=	status;
}



/*******************************
*函数名称：FSM_OutputDataLenth
*函数功能：输出数据长度
*输入参数：none
*输出参数：none
*返回值  ：数据长度
*******************************/
uint16_t FSM_OutputDataLenth(void)
{
	return FSM.lenth;
}




/*********************************
*函数名称： FSM_ReceivePackage
*函数功能： FSM工作开始接收数据包
*输入参数： 接收到的数据
*输出参数： none
*********************************/
void FSM_ReceivePackage(uint16_t dat)
{
	static uint16_t datalenth	=	0;
	switch(FSM_GetStatus())
	{
            case FSM_CHECK_H_HEAD_STATUS:
              if(dat == (FSM_DATA_HEAD & 0x00ff))
                  FSM_ChangeStatus(FSM_CHECK_L_HEAD_STATUS);
              break;
            case FSM_CHECK_L_HEAD_STATUS:
              if(dat	==	(FSM_DATA_HEAD >> 8))
                  FSM_ChangeStatus(FSM_L_DATA_LENTH_STATUS);
              else if(dat == (FSM_DATA_HEAD & 0x00ff))
                  break;
              else
                  FSM_ChangeStatus(FSM_INIT_STATUS);				
              break;		
            case FSM_L_DATA_LENTH_STATUS:
                  FSM.lenth	=	dat;
                  FSM_ChangeStatus(FSM_H_DATA_LENTH_STATUS);
                break;
            case FSM_H_DATA_LENTH_STATUS:
                  FSM.lenth	|=	dat << 8;
            if(FSM.lenth >= RCV_BUF_MAX_SIZE)
                FSM_Init();
            else
            {
                datalenth	=	0;					//请datalenth 开始下一次接收数据
                RAM_CleanRcvBuf();						//清除要保存数据的RAM空间
                FSM_ChangeStatus(FSM_RCV_DATA_STATUS);
            }
            break;
            case FSM_RCV_DATA_STATUS:
                if(datalenth	<	FSM.lenth)
                {
                    RAM_SaveDataToRcvBuf(dat);			                //将接收到的数据存到RAM
                    datalenth++;
                }
                if(datalenth	>=	FSM.lenth)			        //如果接收完成则改变状态机状态
                    FSM_ChangeStatus(FSM_STOP_STATUS);					            
                break;
            case FSM_STOP_STATUS:
                break;
	}	
}



//将发送buf中的数据打包 然后通过串口发送出去
/*********************************
*函数名称：FSM_SendPackage
*函数功能：将发送buf中的数据打包 然后通过串口发送出去
*输入参数：none
*输出参数：none
*********************************/
void FSM_SendPackage(void)
{
    uint16_t lenth  =   RAM_GetDataLenthOfSendBuf();					//获取发送buf中的数据长度
	if(lenth	==	0)													//如果发送buf中没有数据的话就直接退出
		return;
	//发送头
	UARTSendChar(USART_CMD_CHANNEL,(FSM_DATA_HEAD&0x00ff));
	UARTSendChar(USART_CMD_CHANNEL,(FSM_DATA_HEAD>>8));
	//发送数据长度
	UARTSendChar(USART_CMD_CHANNEL,(lenth & 0x00ff));
	UARTSendChar(USART_CMD_CHANNEL,(lenth >> 8));
	//发送数据体
	for(uint16_t i = 0;i < lenth;i++)
		UARTSendChar(USART_CMD_CHANNEL,RAM_TakeOutDataFromSendBuf());				//将数据从发送buf中取出并通过串口发送出去
}
